package org.lanyu.springainovel.chat.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.lanyu.springainovel.common.config.ChatModelManager;
import org.lanyu.springainovel.common.entity.AiModel;
import org.lanyu.springainovel.common.entity.MyPromptTemplate;
import org.lanyu.springainovel.chat.mapper.PromptTemplateMapper;
import org.lanyu.springainovel.common.service.AiModelService;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.reactive.function.client.WebClientRequestException;
import reactor.core.publisher.Flux;

import java.util.List;

@Service
@AllArgsConstructor
@Slf4j
public class PromptTemplateService {

    private final PromptTemplateMapper promptTemplateMapper;
    private final ChatModelManager chatModelManager;
    private final AiModelService aiModelService;


    public List<MyPromptTemplate> getAllActiveTemplates() {
        return promptTemplateMapper.selectList(
            new QueryWrapper<MyPromptTemplate>().eq("status", true)
        );
    }

    public List<MyPromptTemplate> getTemplatesByCategory(String category) {
        return promptTemplateMapper.selectList(
            new QueryWrapper<MyPromptTemplate>().eq("category", category).eq("status", true)
                    .select(MyPromptTemplate.class, info -> !info.getColumn().equals("content"))
        );
    }

    public List<MyPromptTemplate> searchTemplatesByTag(String tag) {
        return promptTemplateMapper.selectList(
            new QueryWrapper<MyPromptTemplate>().like("tags", tag).eq("status", true)
        );
    }

    public List<MyPromptTemplate> searchTemplatesByName(String name) {
        return promptTemplateMapper.selectList(
            new QueryWrapper<MyPromptTemplate>().like("name", name).eq("status", true).orderByDesc("usage_count")
        );
    }

    public MyPromptTemplate getTemplateById(Long id) {
        return promptTemplateMapper.selectById(id);
    }

    @Transactional
    public MyPromptTemplate saveTemplate(MyPromptTemplate template) {
        if (template.getId() == null ) {
            promptTemplateMapper.insert(template);
        } else {
            promptTemplateMapper.updateById(template);
        }
        return template;
    }

    @Transactional
    public void incrementUsageCount(Long templateId) {
        MyPromptTemplate template = promptTemplateMapper.selectById(templateId);
        if (template != null) {
            template.setUsageCount(template.getUsageCount() + 1);
            promptTemplateMapper.updateById(template);
        }
    }

    @Transactional
    public void deleteTemplate(Long id) {
        MyPromptTemplate template = promptTemplateMapper.selectById(id);
        if (template != null) {
            template.setStatus(false);
            promptTemplateMapper.updateById(template);
        }
    }

    /**
     * 处理提示词模板测试流式请求
     *
     * @param message 用户消息
     * @param systemPrompt 系统提示词
     * @param modelId 模型ID
     * @return 流式响应
     */
    public Flux<String> processPromptTest(String message, String systemPrompt, Long modelId) {
        try {
            // 获取模型配置
            AiModel modelConfig = aiModelService.findById(modelId);
            if (modelConfig == null) {
                return Flux.just("错误: 未找到指定模型ID: " + modelId);
            }

            ChatModel chatModel;
            try {
                chatModel = chatModelManager.getOrCreateChatModel(modelConfig);
            } catch (Exception e) {
                log.error("创建聊天模型失败: {}", e.getMessage());
                if (e.getCause() instanceof WebClientRequestException ||
                        e.getMessage().contains("Connection refused") ||
                        e.getMessage().contains("ConnectException")) {
                    return Flux.just("该模型暂不支持");
                }
                return Flux.just("模型创建失败: " + e.getMessage());
            }

            // 创建ChatClient
            ChatClient chatClient = ChatClient.builder(chatModel).build();

            // 生成流式响应
            Flux<String> response;
            if (systemPrompt != null && !systemPrompt.trim().isEmpty()) {
                response = chatClient.prompt()
                        .system(systemPrompt)
                        .user(message)
                        .stream()
                        .content();
            } else {
                response = chatClient.prompt()
                        .user(message)
                        .stream()
                        .content();
            }

            return response
                    .doOnComplete(() -> {
                        log.info("提示词测试完成，模型ID: {}", modelId);
                    })
                    .onErrorResume(throwable -> {
                        log.error("提示词测试流式接口发生异常", throwable);

                        // 特殊处理模型连接异常
                        if (throwable instanceof WebClientRequestException ||
                                (throwable.getCause() instanceof WebClientRequestException)) {
                            log.warn("模型连接失败，可能是模型不在线或服务不可用");
                            return Flux.just("模型不在线或服务不可用");
                        }

                        // 其他异常返回通用错误信息
                        return Flux.just("错误: " + throwable.getMessage());
                    });
        } catch (Exception e) {
            log.error("提示词测试流式接口同步异常", e);
            return Flux.just("系统错误: " + e.getMessage());
        }
    }
}
